<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Canvas 简易版贪吃蛇</title>
    <link rel="shortcut icon" href="./images/snakeIcon.png" type="image/x-icon">
    <link rel="stylesheet" href="./css/snake.css">
</head>

<body>
    <div class="wrapper">
    </div>
    <canvas height="300" width="1360" id="canvas"
        style="position: absolute;top: 0;left: 0;right: 0;bottom: 0;"></canvas>
    <script src="./js/vue.min.js"></script>
    <script>
        var canvasEl = document.getElementById("canvas");
        var ctx = canvasEl.getContext("2d");


        var vx = 8;
        var vy = 8;
        var snakeArr = [];

        for (var i = 0; i <= 5; i++) {
            var node = {
                x: i * 8,
                y: 8,
                w: 8,
                h: 8,
                dir: 'right'
            }


            snakeArr.unshift(node);
        }

        var direction = 'right';
        var gameOver = 'false';


        window.onresize = function () {
            canvasEl.width = document.body.clientWidth;
            canvasEl.height = document.body.clientHeight;
        };

        window.onresize();

        window.onkeydown = function (ev) {
            keyDown(ev);
        }

        function keyDown(ev) {
            this.keyCode = ev.keyCode;
            if (ev.keyCode == 39) {
                if (direction == 'left') {
                    return;
                }
                direction = "right";
            }
            if (ev.keyCode == 37) {
                if (direction == 'right') {
                    return;
                }
                direction = "left";
            }
            if (ev.keyCode == 38) {
                if (direction == 'down') {
                    return;
                }
                direction = "top";
            }
            if (ev.keyCode == 40) {
                if (direction == 'top') {
                    return;
                }
                direction = "down";
            }

            ev.preventDefault();
        }


        // 初始化贪吃蛇
        function initSnake() {
            snakeArr.forEach((snake, index) => {
                ctx.fillStyle = index == 0 ? 'red' : '#fff';
                ctx.beginPath();
                ctx.arc(snake.x, snake.y, 4, 0, 2 * Math.PI);
                ctx.fill();
            })
        }


        var foodX = Math.random() * canvasEl.width;
        var foodY = Math.random() * canvasEl.height;
        var r = parseInt((Math.random() * 5) + 5);
        // 初始化食物
        function initFood() {
            ctx.fillStyle = "rgba(" + (Math.random() * 255) + "," + (Math.random() *
                255) + "," + (Math.random() * 255) + ")";
            ctx.beginPath();
            ctx.arc(foodX, foodY, r, 0, 2 * Math.PI);
            ctx.fill();
        }

        // 改变食物的位置
        function changeFood() {
            foodX = Math.random() * canvasEl.width;
            foodY = Math.random() * canvasEl.height;
            r = parseInt((Math.random() * 5) + 5);
        }

        // 判断是否咬到自身
        function touchSelf(head) {
            snakeArr.forEach((item, index) => {
                if (index != 0) {
                    let length = Math.sqrt(
                        Math.pow(head.x - item.x, 2) + Math.pow(head.y - item.y, 2)
                    );
                    if (length < vx) {
                        gameOver = 'true';
                    }
                }
            })
        }

        // 移动1
        function snakeMove() {
            let newFireNode = {
                x: 8,
                y: 8,
                w: 5,
                h: 5,
            }
            if (gameOver == 'false') {
                if (direction == 'right') {
                    newFireNode.x = snakeArr[0].x + vx;
                    newFireNode.y = snakeArr[0].y;
                }
                if (direction == 'down') {
                    newFireNode.y = snakeArr[0].y + vy;
                    newFireNode.x = snakeArr[0].x;
                }
                if (direction == 'left') {
                    newFireNode.x = snakeArr[0].x - vx;
                    newFireNode.y = snakeArr[0].y;
                }
                if (direction == 'top') {
                    newFireNode.y = snakeArr[0].y - vy;
                    newFireNode.x = snakeArr[0].x;
                }

                if ((newFireNode.x >= (foodX - 10) && newFireNode.x <= (foodX + 10)) && (newFireNode.y >= (foodY -
                        10) && newFireNode.y <= (foodY + 10))) {
                    changeFood();
                    foodNum += 1;
                    snakeArr.unshift(newFireNode);
                    if (r >= 8) {
                        let lastNode = snakeArr[snakeArr.length - 1];
                        snakeArr.push(lastNode);
                    }
                }

                if (newFireNode.x >= canvasEl.width || newFireNode.x < 0) {
                    gameOver = 'true';
                }
                if (newFireNode.y <= 0 || newFireNode.y >= canvasEl.height) {
                    gameOver = 'true';
                }

                touchSelf(newFireNode);

                snakeArr.unshift(newFireNode)
                snakeArr.pop();
            }


            // render();
            // window.requestAnimationFrame(snakeMove);
        }






        // 渲染
        function render() {

            // 绘制黑色背景的画布
            ctx.fillStyle = "#000";
            ctx.fillRect(0, 0, canvasEl.width, canvasEl.height);


            // 初始化贪吃蛇
            initSnake();

            initFood();

            ctx.globalAlpha = 1.0;
        }


        var timer = null;
        var time = 50;
        var foodNum = 0;
        var app = new Vue({
            el: '.wrapper',
            data: {
                showTip: false,
                tip: "请输入合理数值"
            },
            created() {
                this.start();
            },
            methods: {

                start() {
                    // render();
                    // window.requestAnimationFrame(snakeMove);

                    timer = setTimeout(() => {
                        render();
                        snakeMove();
                        this.start();
                    }, time)
                    if (foodNum > 0 && foodNum % 10 == 0) {
                        clearTimeout(timer);
                        timer = null;
                        time  -= 1;
                        foodNum = 0;
                        app && app.start();
                    }
                }
            }
        })
    </script>
</body>

</html>